package com.ruoyi.system.util;

import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ruoyi.common.utils.StringUtils;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

@Component
public class WxPayV3Util
{
    private static final Logger log = LoggerFactory.getLogger(WxPayV3Util.class);

    private static final String schema = "WECHATPAY2-SHA256-RSA2048";

    /**
     * @param requestType HTTP请求方法类型  GET\POST\PUT\DELETE
     * @param url        URL
     * @param timestamp  请求时间戳
     * @param nonceStr   请求随机串
     * @param body       请求报文主体 部分get请求是没有body请求体的
     */
    public static String getSignContent(String requestType, String url, long timestamp, String nonceStr, String body) {
        StringBuilder signContent = new StringBuilder();
        signContent.append(requestType).append("\n");
        signContent.append(url.substring(url.indexOf("/v3"))).append("\n");
        signContent.append(timestamp).append("\n");
        signContent.append(nonceStr).append("\n");
        if (StringUtils.isNotEmpty(body)) {
            signContent.append(body).append("\n");
        } else {
            signContent.append("\n");
        }
        return signContent.toString();
    }


    public static String getSignContentResult(String appId,long timestamp, String nonceStr, String packages) {
        StringBuilder signContent = new StringBuilder();
        signContent.append(appId).append("\n");
        signContent.append(timestamp).append("\n");
        signContent.append(nonceStr).append("\n");
        signContent.append(packages).append("\n");
        System.out.println(signContent);
        return signContent.toString();
    }


    public static String signMessage(String message, String pemPrivateKey) throws Exception {
        // 生成 PrivateKey 对象
        //PrivateKey privateKey = getPrivateKey("D:\\小程序巨量\\apiclient_key.pem");
        // 创建 Signature 对象
        Signature signature = Signature.getInstance("SHA256withRSA");

        // 初始化 Signature 对象
       // if(StringUtils.isNotEmpty(pemPrivateKey)){
            PrivateKey privateKey = getPrivateKeyStr(pemPrivateKey);
            signature.initSign(privateKey);
       // }

        // 提供待签名的消息
        signature.update(message.getBytes("UTF-8"));

        // 生成签名并进行 Base64 编码
        byte[] signedData = signature.sign();
        return Base64.getEncoder().encodeToString(signedData);
    }

    /**
     * 获取私钥。
     *
     * @param filename 私钥文件路径  (required)
     * @return 私钥对象
     */
    public static PrivateKey getPrivateKeyStr(String filename) throws IOException, IOException {

        try {
            String privateKey = filename.replace("-----BEGIN PRIVATE KEY-----", "")
                    .replace("-----END PRIVATE KEY-----", "")
                    .replaceAll("\\s+", "");

            KeyFactory kf = KeyFactory.getInstance("RSA");
            return kf.generatePrivate(
                    new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("当前Java环境不支持RSA", e);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException("无效的密钥格式");
        }
    }

    /**
     * 获取私钥。
     *
     * @param filename 私钥文件路径  (required)
     * @return 私钥对象
     */
    public static PrivateKey getPrivateKey(String filename) throws IOException, IOException {

        String content = new String(Files.readAllBytes(Paths.get(filename)), "utf-8");
        try {
            String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
                    .replace("-----END PRIVATE KEY-----", "")
                    .replaceAll("\\s+", "");

            KeyFactory kf = KeyFactory.getInstance("RSA");
            return kf.generatePrivate(
                    new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("当前Java环境不支持RSA", e);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException("无效的密钥格式");
        }
    }
}
